package com.chixing.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.chixing.entity.OrderExtension;
import com.chixing.entity.OrderTransactions;
import com.chixing.entity.VO.OrderVO;
import com.chixing.service.IOrderExtensionService;
import com.chixing.service.IOrderTransactionsService;
import com.chixing.service.IOrdersService;
import com.chixing.service.IRoomInventoryService;
import com.chixing.utils.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * <p>
 *  支付宝支付控制器（新版 SDK 改写）
 * </p>
 *
 * @author smith
 * @since 2025-09-30
 */
@CrossOrigin
@RestController
@RequestMapping("/order-transactions")
public class OrderTransactionsController {

    @Autowired
    private IOrderTransactionsService flowService;
    @Autowired
    private IRoomInventoryService roomInventoryService;
    @Autowired
    private IOrdersService myorderService;
    @Autowired
    private IOrderExtensionService orderExtensionService;

    /**
     * ======================= 调用支付宝支付（新版 SDK 写法） =======================
     */
    @PostMapping
    public void alipay(@RequestBody OrderVO myorder, HttpServletResponse response) throws AlipayApiException, IOException {
        System.out.println("通过幂等性验证，开始调用支付宝接口...");
        System.out.println("支付alipay orderID = " + myorder.getOrderId());

        // === 1. 初始化 AlipayConfig ===
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(com.chixing.config.AlipayConfig.gatewayUrl);
        alipayConfig.setAppId(com.chixing.config.AlipayConfig.app_id);
        alipayConfig.setPrivateKey(com.chixing.config.AlipayConfig.merchant_private_key);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(com.chixing.config.AlipayConfig.alipay_public_key);
        alipayConfig.setCharset(com.chixing.config.AlipayConfig.charset);
        alipayConfig.setSignType(com.chixing.config.AlipayConfig.sign_type);

        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);

        // === 2. 创建支付请求对象 ===
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(com.chixing.config.AlipayConfig.return_url);
        request.setNotifyUrl(com.chixing.config.AlipayConfig.notify_url);

        // === 3. 构建请求参数模型 ===
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(myorder.getOrderNumber()); // 商户订单号
        model.setTotalAmount(String.valueOf(myorder.getOrderPrice())); // 金额
        model.setSubject(myorder.getHotelName()); // 订单标题
        model.setBody(""); // 描述
        model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 产品码

        request.setBizModel(model);

        // === 4. 执行请求 ===
        String result = alipayClient.pageExecute(request).getBody();

        // === 5. 直接输出 HTML 给浏览器渲染 ===
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write(result);
    }


    /**
     * ======================= 支付成功后同步回调 =======================
     */
    @GetMapping("alipayReturnNotice")
    public void alipayReturnNotice(HttpServletRequest request, HttpServletResponse response)
            throws IOException, AlipayApiException {

        String orderNum = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String payPrice = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

        System.out.println("同步回调订单号:" + orderNum + ", 支付宝交易号:" + tradeNo + ", 金额:" + payPrice);

        // 查询完整订单
        OrderVO orderVO = (OrderVO) flowService.getOrderDetailsByNumber(orderNum).getData();
        if (orderVO == null) {
            OrderExtension extension = orderExtensionService.getByTradeNo(orderNum);
            if (extension != null) {
                // 创建延迟退房流水
                OrderTransactions flow = new OrderTransactions();
                flow.setOrderId(extension.getOrderId());
                flow.setTransactionsNo(UUID.randomUUID().toString().replace("-", ""));
                flow.setCreatedAt(LocalDateTime.now());
                flow.setTransactionsStatus("已支付");
                flow.setAmount(extension.getExtensionFee());
                flow.setCompletedType("延迟退房支付");
                flowService.save(flow);

                // 更新延迟退房状态
                //extension.setExtensionStatus("已支付");
                orderExtensionService.updateStatusById(extension.getExtensionId(),"已支付");

                // 跳转前端
                response.sendRedirect("http://localhost:5173/flowDetail/" + flow.getTransactionsId());
                return;
            }
            // 普通订单也没有
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "订单不存在或尚未支付");
            return;
        }

        // === 更新库存 ===
        System.out.println("库存更新开始");
        roomInventoryService.decrLockCountAddBookedCount(orderVO.getHotelId(),
                orderVO.getCheckIn(),
                orderVO.getCheckOut(),
                orderVO.getRoomtypeId());
        System.out.println("库存更新结束");

        // === 创建流水 ===
        OrderTransactions flow = new OrderTransactions();
        flow.setOrderId(orderVO.getOrderId());
        flow.setTransactionsNo(UUID.randomUUID().toString().replace("-", ""));
        flow.setCreatedAt(LocalDateTime.now());
        flow.setTransactionsStatus("已支付");
        flow.setAmount(orderVO.getOrderPrice());
        flow.setCompletedType("支付");

        Result result = flowService.save(flow);
        System.out.println("创建流水成功");

        OrderTransactions savedFlow = (OrderTransactions) result.getData();

        // 页面跳转到前端
        String vueUrl = "http://localhost:5173/flowDetail/" + savedFlow.getTransactionsId();
        response.sendRedirect(vueUrl);
    }

    /**
     * ======================= 支付宝异步回调 =======================
     */
    @PostMapping("alipayNotifyNotice")
    @ResponseBody
    public String alipayNotifyNotice(HttpServletRequest request) throws UnsupportedEncodingException {

        String orderNum = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String payPrice = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

        System.out.println("异步回调订单号:" + orderNum + ", 支付宝交易号:" + tradeNo + ", 金额:" + payPrice);

        // 查询完整订单
        OrderVO orderVO = (OrderVO) flowService.getOrderDetailsByNumber(orderNum).getData();
        if (orderVO == null) {
            System.err.println("异步回调失败：订单不存在 orderNum=" + orderNum);
            return "fail";
        }

        // === 更新库存 ===
        System.out.println("库存更新开始");
        roomInventoryService.decrLockCountAddBookedCount(orderVO.getHotelId(),
                orderVO.getCheckIn(),
                orderVO.getCheckOut(),
                orderVO.getRoomtypeId());
        System.out.println("库存更新结束");

        // === 创建流水 ===
        OrderTransactions flow = new OrderTransactions();
        flow.setOrderId(orderVO.getOrderId());
        flow.setTransactionsNo(UUID.randomUUID().toString().replace("-", ""));
        flow.setCreatedAt(LocalDateTime.now());
        flow.setTransactionsStatus("已支付");
        flow.setAmount(orderVO.getOrderPrice());
        flow.setCompletedType("支付");

        System.out.println("开始创建支付流水...");
        flowService.save(flow);

        return "success";
    }

    /**
     * ======================= 查询交易详情 =======================
     */
    @GetMapping("/searchAll/{transactionsId}")
    public Result getAllVOByOrderTransaction(@PathVariable Long transactionsId) {
        return flowService.getOrderAllByTransactionsId(transactionsId);
    }
}
